﻿using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using ScannerApp.ScannerWebserviceWrapper;
using System.Text.RegularExpressions;

using ScannerApp.Utils;
using CodeBetter.Json;
using System.Collections;

namespace ScannerApp.Forms
{

    public partial class InStockForm : ScannerBaseForm
    {
        protected InStockOrderResult mOrder;
        protected bool mInitFinishFlag = false;
        private int currentOrderIndex = 1;
        private int currentScanIndex = 1;

        public InStockForm()
        {
            InitializeComponent();
        }

        public override void Init()
        {
            base.Init();
            mCurrentStatus = ScanBarcodeStatus.InStockCode;
            mCurrentProductBarcodeType = ProductBarcodeType.Unknown;
            this.dgOrder.TableStyles.Add(Utils.Utils.GetTableStyle(typeof(MergedInBoxProduct)));
            this.dgScan.TableStyles.Add(Utils.Utils.GetTableStyle(typeof(ScannedInStockGoods)));
            DispalyMessage("请选择入库单号");
            BindOrderList();

        }
        public override void AssignControls()
        {
            this.lblMessage = this.labTitle;
            this.txtScanCode = this.txtScan;
            this.lblProductInfo = this.lblScanedInfo;
            this.lblHeaderInfo = this.lblHeader;
        }

        public void BindOrderList()
        {
            mInitFinishFlag = false;
            InStockProductsParameter param = new InStockProductsParameter();

            String strResult = ScannerWebServiceProxy.Instance.inStockOrderGetList(Converter.Serialize(param));
            BaseResult<InStockOrderListResult> result = Converter.Deserialize<BaseResult<InStockOrderListResult>>(strResult);
            if (result.IsSucessful())
            {
                txtScan.DisplayMember = "AsnNumber";
                txtScan.DataSource = result.ReturnValue.inStockOrderList;

            }
            mInitFinishFlag = true;
        }

        private void BindData(InStockOrderResult order,string message, int pageSize)
        {
            DispalyMessage(message);

            if (order != null)
            {
                mOrder = order;
                this.mScanProductOrder = order;
                this.currentOrderIndex = order.OrderPageIndex;
                this.currentScanIndex = order.ScanPageIndex;

                RefreshOrderGrid(Utils.Utils.ConvertListToDataTable(order.GetMergedInBoxProducts()), order.OrderPageIndex, order.OrderTotalPage, pageSize, order.OrderTotalCount);
                RefreshScanGrid(Utils.Utils.ConvertListToDataTable(order.scannedGoods), order.ScanPageIndex, order.ScanTotalPage, pageSize, order.ScanTotalCount);

                EnablingPutOnShelfMenu();
            }
            else
            {
                mOrder = null;
                this.mScanProductOrder = null;
                this.dgOrder.DataSource = null;
                this.dgScan.DataSource = null;
            }
            
        }

        private void EnablingPutOnShelfMenu()
        {
            if (this.mOrder.IsEnablingPutOnShelf())
            {
                if (!this.mnuOperate.MenuItems.Contains(this.menuPutOnShelf))
                {
                    this.mnuOperate.MenuItems.Add(this.menuPutOnShelf);
                }
            }
            else
            {
                if (this.mnuOperate.MenuItems.Contains(this.menuPutOnShelf))
                {
                    this.mnuOperate.MenuItems.Remove(this.menuPutOnShelf);
                }
            }
        }

        public override void HandleBarCode(string barCode)
        {
            try
            {
                base.HandleBarCode(barCode);

                if (barCode.Equals(string.Empty))
                {
                    return;
                }
              
                if (mCurrentStatus == ScanBarcodeStatus.InStockCode)
                {
                    ScanInStockCode(barCode);
                }
                else if (mCurrentStatus == ScanBarcodeStatus.ShelfCode)
                {
                    ScanShelfCode(barCode);
                }
                else if (mCurrentStatus == ScanBarcodeStatus.ProductCode)
                {
                    ScanProductCode(barCode,this.mOrder);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ScanInStockCode(string barCode)
        {
            InStockProductsParameter param = new InStockProductsParameter();
            param.InStockCode = barCode;

            String strResult = ScannerWebServiceProxy.Instance.inStockOrder(Converter.Serialize(param));
            BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
            if (result.IsSucessful())
            {
                if (!result.ReturnValue.IsFinishedStatus())
                {
                    mOrderCode = barCode;
                    BindData(result.ReturnValue, "获取入库单数据成功.请扫描货位号", param.pageSize);
                    mCurrentStatus = ScanBarcodeStatus.ShelfCode;
                }
                else
                {
                    BindData(result.ReturnValue, "此入库单为已完成状态,不能对其操作.请选择入库单号", param.pageSize);
                    mCurrentStatus = ScanBarcodeStatus.InStockCode;
                }
            }
            else
            {
                BindData(null, result.getReturnCodeMessage(), param.pageSize);
            }
        }

        private void ScanShelfCode(string barCode)
        {
            if (this.IsShelfcode(barCode, mOrder.recHeadGoodsInfo.warehouseid))
            {
                this.mCurrentShelfCode = barCode;
                this.mCurrentStatus = ScanBarcodeStatus.ProductCode;
                this.DispalyMessage("已扫描此货位，请扫描一级码或者序列号.");
            }
            else
            {
                DispalyMessage("货位与订单不符,请扫描正确的货位.");
            }
        }

        protected override  void ScanQRCode(string QRcode)
        {
            Regex reg = new Regex("^[0-9a-zA-Z]+$");
            if (QRcode.Length < 15 || QRcode.Length > 20 || !reg.IsMatch(QRcode))
            {
                DispalyMessage("扫描序列号格式不正确.");
                return;
            }

            if (this.mOrder.IsRepeatedScan(this.mOrderCode, QRcode))
            {
                DispalyMessage("此码已经被扫描过了");
                return;
            }

            if (this.mOrder.IfValidQuantity(this.mCurrentProductCode, this.mCurrentProductLot,1) == false)
            {
                DispalyMessage("数量不匹配");
                return;
            }

            this.mCurrentProductQR = QRcode;
            this.DispalyProductMessage();

            InStockSingleProductParameter param = new InStockSingleProductParameter();
            param.InStockCode = this.mOrderCode;
            param.ShelfCode = this.mCurrentShelfCode;
            param.ProductCode = QRcode;
            param.Quantity = 1;
            param.InventoryCode = this.mCurrentProductCode;
            param.Lot = this.mCurrentProductLot;
            param.Validity = this.mCurrentProductValidity;
            param.currentPage = this.currentOrderIndex;
            param.currentScanPage = this.currentScanIndex;
            param.searchType = 1;

            
            string strResult = ScannerWebServiceProxy.Instance.inStockSingleProduct(Converter.Serialize(param));
            BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
            if (result.IsSucessful())
            {
                if (result.ReturnValue.GetMergedInBoxProducts().Count == 0)
                {
                    BindData(result.ReturnValue, "全部产品已扫描成功,请收货.", param.pageSize);
                }
                else
                {
                    this.mCurrentStatus = ScanBarcodeStatus.ProductCode;
                    BindData(result.ReturnValue, "产品扫描成功,请继续扫描一级码或者序列号.", param.pageSize);
                }  
            }
            else
            {
                DispalyMessage(result.getReturnCodeMessage());
            }
        }

        protected override void ScanProductWithQuantity(string productCode, string lot ,float quantity)
        {
            if (this.mOrder.IfValidQuantity(productCode, lot, quantity) == false)
            {
                DispalyMessage("数量不匹配");
                return;
            }

            InStockSingleProductParameter param = new InStockSingleProductParameter();
            param.InStockCode = this.mOrderCode;
            param.ShelfCode = this.mCurrentShelfCode;
            param.InventoryCode = productCode;
            param.Lot = lot;
            param.Quantity = quantity;
            param.currentPage = this.currentOrderIndex;
            param.currentScanPage = this.currentScanIndex;
            param.searchType = 1;

            string strResult = ScannerWebServiceProxy.Instance.inStockSingleProduct(Converter.Serialize(param));
            BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
            if (result.IsSucessful())
            {
                if (result.ReturnValue.GetMergedInBoxProducts().Count == 0)
                {
                    BindData(result.ReturnValue, "全部产品已扫描成功,请收货.", param.pageSize);
                }
                else
                {
                    this.mCurrentStatus = ScanBarcodeStatus.ProductCode;
                    BindData(result.ReturnValue, "产品扫描成功,请继续扫描一级码或者序列号.", param.pageSize);
                }  
            }
            else
            {
                DispalyMessage(result.getReturnCodeMessage());
            }
        }


        private void menuPutOnShelf_Click(object sender, EventArgs e)
        {
            if (this.mOrder == null)
            {
                return;
            }
            PutOnShelf(true);
            
        }

        private void PutOnShelf(bool isMenuPutOnShelfClick)
        {
            InStockPutOnShelfParameter param = new InStockPutOnShelfParameter();
            param.InStockCode = this.mOrderCode;
            param.ShelfCode = this.mCurrentShelfCode;
            param.IfAllFinished = (this.mOrder.GetMergedInBoxProducts().Count == 0) ? true : false;
            param.currentPage = this.currentOrderIndex;
            param.currentScanPage = this.currentScanIndex;
            param.searchType = 1;

            /*
            if (!isMenuPutOnShelfClick)
            {
                param.ProductCode = this.mOrder.recshGoodsList[0].productcode;
            }
            */
            string strResult = ScannerWebServiceProxy.Instance.inStockPutOnShelf(Converter.Serialize(param));
            BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
            if (result.IsSucessful())
            {
                BindData(result.ReturnValue, "已完成上架", param.pageSize);
                if (param.IfAllFinished == true)
                {
                    DispalyMessage("此入库单已完成.");
                    this.BindOrderList();
                }
            }
            else
            {
                DispalyMessage(result.getReturnCodeMessage());
            }
        }

        private void menuInStock_Click(object sender, EventArgs e)
        {
            if (this.mOrder == null)
            {
                DispalyMessage("还未扫描入库单号");
                return;
            }
            if (this.mCurrentShelfCode == null)
            {
                DispalyMessage("还未扫描货位号");
                return;
            }

            if (this.mOrder.scannedGoods != null && this.mOrder.scannedGoods.Count > 0)
            {
                InStockProductsParameter param = new InStockProductsParameter();
                param.InStockCode = this.mOrderCode;
                param.ShelfCode = this.mCurrentShelfCode;
                param.currentPage = this.currentOrderIndex;
                param.currentScanPage = this.currentScanIndex;
                param.searchType = 1;

                String strResult = ScannerWebServiceProxy.Instance.inStockProducts(Converter.Serialize(param));
                BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
                if (result.IsSucessful())
                {
                    // 多条数据全部收货并全部上架的时候
                    bool isAllPutonShelf = this.mOrder.scannedGoods.Count > 1;

                    BindData(result.ReturnValue,"对已扫描的产品收货成功.请扫描新的货位号", param.pageSize);
                    this.mCurrentShelfCode = string.Empty;
                    mCurrentStatus = ScanBarcodeStatus.ShelfCode;
                    this.ClearProductValues();
                    
                    //点击收货完成后，提示是否上架
                    if (MessageBox.Show("是否要上架完成?", "确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.OK)
                    {
                         PutOnShelf(isAllPutonShelf);
                    }
                    EnablingPutOnShelfMenu();               
                }
                else
                {
                    DispalyMessage(result.getReturnCodeMessage());
                }
            }
        }

        private void menuRefresh_Click(object sender, EventArgs e)
        {
            if (mOrderCode == string.Empty)
            {
                return;
            }
            InStockProductsParameter param = new InStockProductsParameter();
            param.InStockCode = mOrderCode;
            param.currentPage = this.currentOrderIndex;
            param.currentScanPage = this.currentScanIndex;
            param.searchType = 1;

            String strResult = ScannerWebServiceProxy.Instance.inStockOrder(Converter.Serialize(param));
            BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
            if (result.IsSucessful())
            {
                BindData(result.ReturnValue, "数据已刷新", param.pageSize); 
            }
            
        }

        private void menuClear_Click(object sender, EventArgs e)
        {
            if (mOrderCode == string.Empty)
            {
                return;
            }
            InStockProductsParameter param = new InStockProductsParameter();
            param.InStockCode = this.mOrderCode;
            param.currentPage = this.currentOrderIndex;
            param.currentScanPage = this.currentScanIndex;
            param.searchType = 1;

            String strResult = ScannerWebServiceProxy.Instance.inStockClearScanedProducts(Converter.Serialize(param));
            BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
            if (result.IsSucessful())
            {
                //this.ClearFirstLayerValues();
                BindData(result.ReturnValue, "已清空扫描的数据", param.pageSize);
            }
            else
            {
                DispalyMessage("清空已扫描产品失败");
            }
        }

        private void menuDelete_Click(object sender, EventArgs e)
        {
            if (this.dgScan.CurrentRowIndex < 0)
            {
                MessageBox.Show("请选择一条已扫描的记录");
            }
            else
            {
                int num = this.dgScan.CurrentRowIndex;
                string productCode=this.mOrder.scannedGoods[num].id.ToString();
                InStockSingleProductParameter param = new InStockSingleProductParameter();
                param.InStockCode = this.mOrderCode;
                param.ProductCode = productCode;
                param.currentPage = this.currentOrderIndex;
                param.currentScanPage = this.currentScanIndex;
                param.searchType = 1;

                string strResult = ScannerWebServiceProxy.Instance.inStockCancelSingleProduct(Converter.Serialize(param));
                BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
                if (result.IsSucessful())
                {
                    //this.ClearFirstLayerValues();
                    BindData(result.ReturnValue, "已取消选定数据", param.pageSize);
                }
                else
                {
                    DispalyMessage("数据未能取消");
                }
                
            }
        }


        private void txtScan_KeyPress(object sender, KeyPressEventArgs e)
        {
            this.HandleKeyPress(e);
        }

        private void txtScan_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (mInitFinishFlag == false)
            {
                return;
            }

            if (this.txtScan.SelectedItem != null)
            {
                this.ScanInStockCode(this.txtScan.Text);
            }
        }

        private void ClearGridData()
        {
            DisplayScannedCode("");
            DispalyMessage("");
            this.currentOrderIndex = 1;
            this.currentScanIndex = 1;
            this.dgOrder.DataSource = null;
            this.dgScan.DataSource = null;
            lbOrderPagination.Text = String.Empty;
            lbScanPagination.Text = String.Empty;
            btnNext.Visible = false;
            btnPrev.Visible = false;
            btnScanNext.Visible = false;
            btnScanPrev.Visible = false;

        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            this.currentOrderIndex++;
            despatchBodyListPagination();
        }

        private void btnPrev_Click(object sender, EventArgs e)
        {
            this.currentOrderIndex--;
            despatchBodyListPagination();
        }

        private void btnScanPrev_Click(object sender, EventArgs e)
        {
            this.currentScanIndex--;
            tempDespatchListScannerPagination();
        }

        private void btnScanNext_Click(object sender, EventArgs e)
        {
            this.currentScanIndex++;
            tempDespatchListScannerPagination();
        }

        private void RefreshOrderGrid(DataTable dataTable, int pageIndex, int totalPage, int pageSize, int totalCount)
        {
            this.dgOrder.DataSource = dataTable;
            if (this.currentOrderIndex == 1)
            {
                this.btnPrev.Enabled = false;
            }
            else
            {
                this.btnPrev.Enabled = true;
            }

            if (this.currentOrderIndex == totalPage)
            {
                this.btnNext.Enabled = false;
            }
            else
            {
                this.btnNext.Enabled = true;
            }
            this.lbOrderPagination.Text = "第" + pageIndex + "/" + totalPage + "页," + "每页" + pageSize + "条," + "共" + totalCount + "条";
            this.btnPrev.Visible = true;
            this.btnNext.Visible = true;
        }

        private void RefreshScanGrid(DataTable dataTable, int pageIndex, int totalPage, int pageSize, int totalCount)
        {
            this.dgScan.DataSource = dataTable;

            if (this.currentScanIndex == 1)
            {
                this.btnScanPrev.Enabled = false;
            }
            else
            {
                this.btnScanPrev.Enabled = true;
            }

            if (this.currentScanIndex == totalPage)
            {
                this.btnScanNext.Enabled = false;
            }
            else
            {
                this.btnScanNext.Enabled = true;
            }
            this.lbScanPagination.Text = "第" + pageIndex + "/" + totalPage + "页," + "每页" + pageSize + "条," + "共" + totalCount + "条";
            this.btnScanPrev.Visible = true;
            this.btnScanNext.Visible = true;
        }

        private void despatchBodyListPagination()
        {
            try
            {
                InStockProductsParameter param = new InStockProductsParameter();
                param.InStockCode = txtScan.Text;
                param.currentPage = this.currentOrderIndex;
                param.searchType = 2;

                String strResult = ScannerWebServiceProxy.Instance.inStockOrder(Converter.Serialize(param));
                BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
                if (result.IsSucessful())
                {
                    this.currentOrderIndex = result.ReturnValue.OrderPageIndex;

                    RefreshOrderGrid(Utils.Utils.ConvertListToDataTable(result.ReturnValue.GetMergedInBoxProducts()), result.ReturnValue.OrderPageIndex
                     , result.ReturnValue.OrderTotalPage, param.pageSize, result.ReturnValue.OrderTotalCount);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void tempDespatchListScannerPagination()
        {
            try
            {
                InStockProductsParameter param = new InStockProductsParameter();
                param.currentScanPage = this.currentScanIndex;
                param.searchType = 3;
                param.InStockCode = txtScan.Text;

                String strResult = ScannerWebServiceProxy.Instance.inStockOrder(Converter.Serialize(param));
                BaseResult<InStockOrderResult> result = Converter.Deserialize<BaseResult<InStockOrderResult>>(strResult);
                if (result.IsSucessful())
                {
                    this.mOrder.scannedGoods = result.ReturnValue.scannedGoods;
                    this.currentScanIndex = result.ReturnValue.ScanPageIndex;
                    RefreshScanGrid(Utils.Utils.ConvertListToDataTable(result.ReturnValue.scannedGoods), result.ReturnValue.ScanPageIndex
                    , result.ReturnValue.ScanTotalPage, param.scanPageSize, result.ReturnValue.ScanTotalCount);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}